﻿using AutoMapper;
using LiuQiuRong.Chat.Infrastructures.Dependencies;
using LiuQiuRong.Chat.Infrastructures.Models;
using LiuQiuRong.Chat.Repositories;
using System;
using System.Collections.Generic;
using System.Linq.Expressions;

namespace LiuQiuRong.Chat.Businesses
{
    public partial class BaseService<TEntity, TDto> : IBaseService<TEntity, TDto> where TEntity : class, IEntity, new() where TDto : class, IDto, new()
    {
        protected IMapper _mapper;
        protected IBaseRepository<TEntity> _repository;

        public HandleResult Result(string output = "success", object extras = null) => new HandleResult(output, extras);

        public virtual TDto GetById<TKey>(TKey id)
            => _mapper.Map<TDto>(_repository.GetById(id));

        public virtual TDto GetByExpression(Expression<Func<TEntity, bool>> expression)
            => _mapper.Map<TDto>(_repository.GetByExpression(expression));

        public virtual (int, HandleResult) Insert(TDto dto)
            => (_repository.Insert(_mapper.Map<TEntity>(dto)), Result());

        public (int, HandleResult) Insert<T, TMap>(TMap dto) where T : class, new() where TMap : class, new()
        => (_repository.Insert(_mapper.Map<T>(dto)), Result());

        public virtual (int, HandleResult) Update(TDto dto)
            => (_repository.Update(_mapper.Map<TEntity>(dto)), Result());

        public (int, HandleResult) Update<T, TMap>(TMap dto) where T : class, new() where TMap : class, new()
              => (_repository.Update(_mapper.Map<T>(dto)), Result());

        public virtual (int, HandleResult) UpdateColumns(TDto dto, Expression<Func<TEntity, object>> columns)
        => (_repository.UpdateColumns(_mapper.Map<TEntity>(dto), columns), Result());

        public (int, HandleResult) UpdateColumns<T, TMap>(TMap dto, Expression<Func<T, object>> columns) where T : class, new() where TMap : class, new()
             => (_repository.UpdateColumns(_mapper.Map<T>(dto), columns), Result());

        public virtual (int, HandleResult) Delete<TKey>(TKey id)
        => (_repository.Delete(id), Result());

        public virtual bool Any(Expression<Func<TEntity, bool>> expression)
            => _repository.Any(expression);

        public virtual IEnumerable<TDto> GetList(Expression<Func<TEntity, bool>> expression, string orderBy = null)
            => _mapper.Map<IEnumerable<TDto>>(_repository.GetList(expression, orderBy));

        public virtual IEnumerable<TDto> GetList(string expression, string orderBy = null)
            => _mapper.Map<IEnumerable<TDto>>(_repository.GetList(expression, orderBy));

        public virtual IEnumerable<TDto> GetListByPage(Expression<Func<TEntity, bool>> expression, string orderBy, int pageIndex, int pageSize, ref int records, ref int totalPage)
            => _mapper.Map<IEnumerable<TDto>>(_repository.GetListByPage(expression, orderBy, pageIndex, pageSize, ref records, ref totalPage));

        public virtual IEnumerable<TDto> GetListByPage(string expression, string orderBy, int pageIndex, int pageSize, ref int totalCount, ref int totalPage)
            => _mapper.Map<IEnumerable<TDto>>(_repository.GetListByPage(expression, orderBy, pageIndex, pageSize, ref totalCount, ref totalPage));
    }
}
